package com.example.util;



import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class IDCardValidator {

    // 身份证地区码
    private static final Map<String, String> AREA_CODES = new HashMap<>();

    static {
        // 省级行政区划代码（部分示例）
        AREA_CODES.put("11", "北京");
        AREA_CODES.put("12", "天津");
        AREA_CODES.put("13", "河北");
        AREA_CODES.put("14", "山西");
        AREA_CODES.put("15", "内蒙");
        AREA_CODES.put("21", "辽宁");
        AREA_CODES.put("22", "吉林");
        AREA_CODES.put("23", "黑龙江");
        AREA_CODES.put("31", "上海");
        AREA_CODES.put("32", "江苏");
        AREA_CODES.put("33", "浙江");
        AREA_CODES.put("34", "安徽");
        AREA_CODES.put("35", "福建");
        AREA_CODES.put("36", "江西");
        AREA_CODES.put("37", "山东");
        AREA_CODES.put("41", "河南");
        AREA_CODES.put("42", "湖北");
        AREA_CODES.put("43", "湖南");
        AREA_CODES.put("44", "广东");
        AREA_CODES.put("45", "广西");
        AREA_CODES.put("46", "海南");
        AREA_CODES.put("50", "重庆");
        AREA_CODES.put("51", "四川");
        AREA_CODES.put("52", "贵州");
        AREA_CODES.put("53", "云南");
        AREA_CODES.put("54", "西藏");
        AREA_CODES.put("61", "陕西");
        AREA_CODES.put("62", "甘肃");
        AREA_CODES.put("63", "青海");
        AREA_CODES.put("64", "宁夏");
        AREA_CODES.put("65", "新疆");
        AREA_CODES.put("71", "台湾");
        AREA_CODES.put("81", "香港");
        AREA_CODES.put("82", "澳门");
        // 可以继续添加更多地区码
    }

    // 身份证校验码权重
    private static final int[] WEIGHT_COEFFICIENT = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

    // 校验码对应表
    private static final char[] CHECK_CODE = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

    /**
     * 验证身份证号码是否有效
     */
    public static boolean isValid(String idCard) {
        if (idCard == null || idCard.trim().isEmpty()) {
            return false;
        }

        idCard = idCard.trim().toUpperCase();

        // 根据长度判断是15位还是18位
        if (idCard.length() == 15) {
            return isValid15(idCard);
        } else if (idCard.length() == 18) {
            return isValid18(idCard);
        } else {
            return false;
        }
    }

    /**
     * 验证15位身份证号码
     */
    private static boolean isValid15(String idCard) {
        // 15位身份证正则：数字
        if (!Pattern.matches("^[0-9]{15}$", idCard)) {
            return false;
        }

        // 验证地区码
        String areaCode = idCard.substring(0, 2);
        if (!AREA_CODES.containsKey(areaCode)) {
            return false;
        }

        // 验证生日
        String birthDate = "19" + idCard.substring(6, 12);
        return isValidBirthDate(birthDate);
    }

    /**
     * 验证18位身份证号码
     */
    private static boolean isValid18(String idCard) {
        // 18位身份证正则：17位数字 + 1位数字或X
        if (!Pattern.matches("^[0-9]{17}[0-9X]$", idCard)) {
            return false;
        }

        // 验证地区码
        String areaCode = idCard.substring(0, 2);
        if (!AREA_CODES.containsKey(areaCode)) {
            return false;
        }

        // 验证生日
        String birthDate = idCard.substring(6, 14);
        if (!isValidBirthDate(birthDate)) {
            return false;
        }

        // 验证校验码
        return verifyCheckCode(idCard);
    }

    /**
     * 验证生日是否有效
     */
    private static boolean isValidBirthDate(String birthDate) {
        if (birthDate == null || birthDate.length() != 8) {
            return false;
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        sdf.setLenient(false); // 严格模式

        try {
            Date date =  sdf.parse(birthDate);

            // 检查日期是否在合理范围内（1900年至今）
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            int year = cal.get(Calendar.YEAR);
            int currentYear = Calendar.getInstance().get(Calendar.YEAR);

            return year >= 1900 && year <= currentYear;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 验证18位身份证的校验码
     */
    private static boolean verifyCheckCode(String idCard) {
        if (idCard.length() != 18) {
            return false;
        }

        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += (idCard.charAt(i) - '0') * WEIGHT_COEFFICIENT[i];
        }

        char expectedCheckCode = CHECK_CODE[sum % 11];
        char actualCheckCode = idCard.charAt(17);

        return expectedCheckCode == actualCheckCode;
    }

    /**
     * 15位身份证转18位
     */
    public static String convert15To18(String idCard15) {
        if (!isValid15(idCard15)) {
            throw new IllegalArgumentException("无效的15位身份证号码");
        }

        // 在15位身份证的第6位插入"19"，变成17位
        StringBuilder sb = new StringBuilder();
        sb.append(idCard15.substring(0, 6))
                .append("19")
                .append(idCard15.substring(6));

        // 计算校验码
        String idCard17 = sb.toString();
        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += (idCard17.charAt(i) - '0') * WEIGHT_COEFFICIENT[i];
        }

        char checkCode = CHECK_CODE[sum % 11];
        sb.append(checkCode);

        return sb.toString();
    }
}
